package com.mqr.wallet.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mqr.wallet.common.cache.LocalCache;
import com.mqr.wallet.common.constant.WalletConstants;
import com.mqr.wallet.common.exception.BaseException;
import com.mqr.wallet.domain.WalletInfo;
import com.mqr.wallet.factory.CashWithdrawalServiceFactory;
import com.mqr.wallet.mapper.WalletInfoMapper;
import com.mqr.wallet.service.WalletInfoService;
import com.mqr.wallet.service.WalletTransactionService;
import com.mqr.wallet.vo.CashResult;
import com.mqr.wallet.vo.WalletVO;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.List;

/**
 * <B>主类名称：</B>WalletServiceImpl<BR>
 * <B>概要说明：</B>钱包服务实现类<BR>
 *
 * @author mqr
 * @since 2023年2月21日 下午12:52:50
 */
@Service
public class WalletInfoInfoServiceImpl implements WalletInfoService {

    /**
     * 钱包信息mapper组件
     */
    @Autowired(required = false)
    private WalletInfoMapper walletInfoMapper;

    /**
     * 钱包流水service组件
     */
    @Autowired(required = false)
    private WalletTransactionService walletTransactionService;

    /**
     * 初始化阶段将用户信息加载到缓存中
     */
    @PostConstruct
    public void init() {
        // 初始化加载用户信息
        cacheWalletInfo();
    }


    /**
     * 更新钱包余额
     *
     * @param walletVO
     */
    @Transactional
    @Override
    public void update(WalletVO walletVO) {
        WalletInfo walletInfo = walletInfoMapper.selectOne(new LambdaQueryWrapper<WalletInfo>().eq(WalletInfo::getUserId,walletVO.getUserId()));
        if (ObjectUtils.isNotEmpty(walletInfo)) {
            // 金额计算统一使用BigDecimal类型
            BigDecimal amount = BigDecimal.valueOf(walletVO.getAmount());
            BigDecimal balance = BigDecimal.valueOf(walletInfo.getBalance());
            // 收入
            if (WalletConstants.NUM_0.equals(walletVO.getOperatorType())) {
                // 直接余额加收入金额
                walletInfo.setBalance(balance.add(amount).doubleValue());
            }
            // 支出
            if (WalletConstants.NUM_1.equals(walletVO.getOperatorType())) {
                // 余额小于支出金额
                if (balance.compareTo(amount) == -1) {
                    throw new BaseException("支出金额不能大于余额！");
                }
                // 设置余额
                walletInfo.setBalance(balance.subtract(amount).doubleValue());
                // 提现方式不为空，走默认提现
                if (StringUtils.isNotBlank(walletVO.getCashBankType())){
                    // 余额不小于支出金额，走工厂获取对应支出实现类完成支出动作
                    CashResult cashResult = CashWithdrawalServiceFactory.doService(walletVO);
                    // 设置提现支出结果
                    walletInfo.setCashResult(cashResult);
                }
            }
            // 设置钱包余额信息
            walletVO.setWalletInfo(walletInfo);
            // 更新余额
            walletInfoMapper.updateById(walletInfo);
            // 新增流水信息
            walletTransactionService.addWalletTransaction(walletVO);
            // 更新缓存
            LocalCache.wallerInfoCache.put(walletInfo.getUserId(), walletInfo);
        }
    }

    /**
     * 根据用户id查询用户钱包信息
     * @param userId 用户id
     * @return
     */
    @Override
    public WalletInfo findByUserId(Integer userId) {
        // 从缓存取用户钱包信息
        return LocalCache.wallerInfoCache.getIfPresent(userId);
    }

    /**
     * 缓存用户钱包信息
     */
    private void cacheWalletInfo() {
        LambdaQueryWrapper<WalletInfo> wrapper = new LambdaQueryWrapper<WalletInfo>();
        List<WalletInfo> list = walletInfoMapper.selectList(wrapper);
        list.forEach(e -> {
            LocalCache.wallerInfoCache.put(e.getUserId(), e);
        });
    }
}
